@@ -1,6 +1,6 @@ |
||
| 1 | 1 |
language: ruby |
| 2 |
+bundler_args: --without development production --deployment |
|
| 2 | 3 |
cache: bundler |
| 3 |
-bundler_args: --without development production |
|
| 4 | 4 |
env: |
| 5 | 5 |
- APP_SECRET_TOKEN=b2724973fd81c2f4ac0f92ac48eb3f0152c4a11824c122bcf783419a4c51d8b9bba81c8ba6a66c7de599677c7f486242cf819775c433908e77c739c5c8ae118d |
| 6 | 6 |
rvm: |
@@ -43,11 +43,28 @@ module LiquidInterpolatable |
||
| 43 | 43 |
end |
| 44 | 44 |
|
| 45 | 45 |
require 'uri' |
| 46 |
- # Percent encoding for URI conforming to RFC 3986. |
|
| 47 |
- # Ref: http://tools.ietf.org/html/rfc3986#page-12 |
|
| 48 | 46 |
module Filters |
| 47 |
+ # Percent encoding for URI conforming to RFC 3986. |
|
| 48 |
+ # Ref: http://tools.ietf.org/html/rfc3986#page-12 |
|
| 49 | 49 |
def uri_escape(string) |
| 50 |
- CGI::escape string |
|
| 50 |
+ CGI.escape(string) rescue string |
|
| 51 |
+ end |
|
| 52 |
+ |
|
| 53 |
+ # Escape a string for use in XPath expression |
|
| 54 |
+ def to_xpath(string) |
|
| 55 |
+ subs = string.to_s.scan(/\G(?:\A\z|[^"]+|[^']+)/).map { |x|
|
|
| 56 |
+ case x |
|
| 57 |
+ when /"/ |
|
| 58 |
+ %Q{'#{x}'}
|
|
| 59 |
+ else |
|
| 60 |
+ %Q{"#{x}"}
|
|
| 61 |
+ end |
|
| 62 |
+ } |
|
| 63 |
+ if subs.size == 1 |
|
| 64 |
+ subs.first |
|
| 65 |
+ else |
|
| 66 |
+ 'concat(' << subs.join(', ') << ')'
|
|
| 67 |
+ end |
|
| 51 | 68 |
end |
| 52 | 69 |
end |
| 53 | 70 |
Liquid::Template.register_filter(LiquidInterpolatable::Filters) |
@@ -43,7 +43,7 @@ module Agents |
||
| 43 | 43 |
client = HipChat::Client.new(interpolated[:auth_token] || credential('hipchat_auth_token'))
|
| 44 | 44 |
incoming_events.each do |event| |
| 45 | 45 |
mo = interpolated(event) |
| 46 |
- client[mo[:room_name]].send(mo[:username], mo[:message], :notify => boolify(mo[:notify]), :color => mo[:color]) |
|
| 46 |
+ client[mo[:room_name]].send(mo[:username][0..14], mo[:message], :notify => boolify(mo[:notify]), :color => mo[:color]) |
|
| 47 | 47 |
end |
| 48 | 48 |
end |
| 49 | 49 |
end |
@@ -115,6 +115,10 @@ |
||
| 115 | 115 |
<%= Utils.jsonify((@agent.new_record? && @agent.options == {}) ? @agent.default_options : @agent.options) %>
|
| 116 | 116 |
</textarea> |
| 117 | 117 |
</div> |
| 118 |
+ |
|
| 119 |
+ <div class="form-group"> |
|
| 120 |
+ <%= f.submit "Save", :class => "btn btn-primary" %> |
|
| 121 |
+ </div> |
|
| 118 | 122 |
</div> |
| 119 | 123 |
</div> |
| 120 | 124 |
</div> |
@@ -135,11 +139,4 @@ |
||
| 135 | 139 |
</div> |
| 136 | 140 |
</div> |
| 137 | 141 |
</div> |
| 138 |
- |
|
| 139 |
- <div class='row'> |
|
| 140 |
- <div class="col-md-12"> |
|
| 141 |
- <%= f.submit "Save", :class => "btn btn-primary" %> |
|
| 142 |
- </div> |
|
| 143 |
- </div> |
|
| 144 |
- |
|
| 145 | 142 |
<% end %> |
@@ -1,4 +1,5 @@ |
||
| 1 | 1 |
require 'spec_helper' |
| 2 |
+require 'nokogiri' |
|
| 2 | 3 |
|
| 3 | 4 |
describe LiquidInterpolatable::Filters do |
| 4 | 5 |
before do |
@@ -11,6 +12,10 @@ describe LiquidInterpolatable::Filters do |
||
| 11 | 12 |
it 'should escape a string for use in URI' do |
| 12 | 13 |
@filter.uri_escape('abc:/?=').should == 'abc%3A%2F%3F%3D'
|
| 13 | 14 |
end |
| 15 |
+ |
|
| 16 |
+ it 'should not raise an error when an operand is nil' do |
|
| 17 |
+ @filter.uri_escape(nil).should be_nil |
|
| 18 |
+ end |
|
| 14 | 19 |
end |
| 15 | 20 |
|
| 16 | 21 |
describe 'validations' do |
@@ -32,4 +37,26 @@ describe LiquidInterpolatable::Filters do |
||
| 32 | 37 |
agent.errors[:options].first.should =~ /not properly terminated/ |
| 33 | 38 |
end |
| 34 | 39 |
end |
| 40 |
+ |
|
| 41 |
+ describe 'to_xpath' do |
|
| 42 |
+ before do |
|
| 43 |
+ def @filter.to_xpath_roundtrip(string) |
|
| 44 |
+ Nokogiri::XML('').xpath(to_xpath(string))
|
|
| 45 |
+ end |
|
| 46 |
+ end |
|
| 47 |
+ |
|
| 48 |
+ it 'should escape a string for use in XPath expression' do |
|
| 49 |
+ [ |
|
| 50 |
+ %q{abc}.freeze,
|
|
| 51 |
+ %q{'a"bc'dfa""fds''fa}.freeze,
|
|
| 52 |
+ ].each { |string|
|
|
| 53 |
+ @filter.to_xpath_roundtrip(string).should == string |
|
| 54 |
+ } |
|
| 55 |
+ end |
|
| 56 |
+ |
|
| 57 |
+ it 'should stringize a non-string operand' do |
|
| 58 |
+ @filter.to_xpath_roundtrip(nil).should == '' |
|
| 59 |
+ @filter.to_xpath_roundtrip(1).should == '1' |
|
| 60 |
+ end |
|
| 61 |
+ end |
|
| 35 | 62 |
end |
@@ -17,7 +17,7 @@ describe Agents::HipchatAgent do |
||
| 17 | 17 |
|
| 18 | 18 |
@event = Event.new |
| 19 | 19 |
@event.agent = agents(:bob_weather_agent) |
| 20 |
- @event.payload = { :room_name => 'test room', :message => 'Looks like its going to rain', username: "Huggin user"}
|
|
| 20 |
+ @event.payload = { :room_name => 'test room', :message => 'Looks like its going to rain', username: "Huggin user "}
|
|
| 21 | 21 |
@event.save! |
| 22 | 22 |
end |
| 23 | 23 |
|
@@ -53,7 +53,7 @@ describe Agents::HipchatAgent do |
||
| 53 | 53 |
describe "#receive" do |
| 54 | 54 |
it "send a message to the hipchat" do |
| 55 | 55 |
any_instance_of(HipChat::Room) do |obj| |
| 56 |
- mock(obj).send(@event.payload[:username], @event.payload[:message], {:notify => false, :color => 'yellow'})
|
|
| 56 |
+ mock(obj).send(@event.payload[:username][0..14], @event.payload[:message], {:notify => false, :color => 'yellow'})
|
|
| 57 | 57 |
end |
| 58 | 58 |
@checker.receive([@event]) |
| 59 | 59 |
end |
@@ -456,7 +456,10 @@ fire: hot |
||
| 456 | 456 |
before do |
| 457 | 457 |
@event = Event.new |
| 458 | 458 |
@event.agent = agents(:bob_rain_notifier_agent) |
| 459 |
- @event.payload = { 'url' => "http://xkcd.com" }
|
|
| 459 |
+ @event.payload = {
|
|
| 460 |
+ 'url' => 'http://xkcd.com', |
|
| 461 |
+ 'link' => 'Random', |
|
| 462 |
+ } |
|
| 460 | 463 |
end |
| 461 | 464 |
|
| 462 | 465 |
it "should scrape from the url element in incoming event payload" do |
@@ -467,17 +470,25 @@ fire: hot |
||
| 467 | 470 |
end |
| 468 | 471 |
|
| 469 | 472 |
it "should interpolate values from incoming event payload" do |
| 470 |
- @event.payload['title'] = 'XKCD' |
|
| 471 |
- |
|
| 472 | 473 |
lambda {
|
| 473 |
- @valid_options['extract']['site_title'] = {
|
|
| 474 |
- 'css' => "#comic img", 'value' => "'{{title}}'"
|
|
| 474 |
+ @valid_options['extract'] = {
|
|
| 475 |
+ 'from' => {
|
|
| 476 |
+ 'xpath' => '*[1]', |
|
| 477 |
+ 'value' => '{{url | to_xpath}}'
|
|
| 478 |
+ }, |
|
| 479 |
+ 'to' => {
|
|
| 480 |
+ 'xpath' => '(//a[@href and text()={{link | to_xpath}}])[1]',
|
|
| 481 |
+ 'value' => '@href' |
|
| 482 |
+ }, |
|
| 475 | 483 |
} |
| 476 | 484 |
@checker.options = @valid_options |
| 477 | 485 |
@checker.receive([@event]) |
| 478 | 486 |
}.should change { Event.count }.by(1)
|
| 479 | 487 |
|
| 480 |
- Event.last.payload['site_title'].should == 'XKCD' |
|
| 488 |
+ Event.last.payload.should == {
|
|
| 489 |
+ 'from' => 'http://xkcd.com', |
|
| 490 |
+ 'to' => 'http://dynamic.xkcd.com/random/comic/', |
|
| 491 |
+ } |
|
| 481 | 492 |
end |
| 482 | 493 |
end |
| 483 | 494 |
end |